The section describes the programming interface of the ENET Peripheral Driver.
More...
|
| uint32_t | enet_mii_read (uint32_t instance, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) |
| | (R)MII Read function. More...
|
| |
| uint32_t | enet_mii_write (uint32_t instance, uint32_t phyAddr, uint32_t phyReg, uint32_t data) |
| | (R)MII Read function. More...
|
| |
| uint32_t | enet_mac_bd_init (enet_dev_if_t *enetIfPtr) |
| | Initializes ENET buffer descriptors. More...
|
| |
| uint32_t | enet_mac_mii_init (enet_dev_if_t *enetIfPtr) |
| | Initializes the ENET MAC MII(MDC/MDIO) interface. More...
|
| |
| uint32_t | enet_mac_rxbd_init (enet_dev_if_t *enetIfPtr, enet_rxbd_config_t *rxbdCfg) |
| | Initialize the ENET receive buffer descriptors. More...
|
| |
| uint32_t | enet_mac_rxbd_deinit (enet_dev_if_t *enetIfPtr) |
| | Deinitialize the ENET receive buffer descriptors. More...
|
| |
| uint32_t | enet_mac_txbd_init (enet_dev_if_t *enetIfPtr, enet_txbd_config_t *txbdCfg) |
| | Initialize the ENET transmit buffer descriptors. More...
|
| |
| uint32_t | enet_mac_txbd_deinit (enet_dev_if_t *enetIfPtr) |
| | Deinitialize the ENET transmit buffer descriptors. More...
|
| |
| uint32_t | enet_mac_configure_fifo_accel (enet_dev_if_t *enetIfPtr) |
| | Initializes ENET MAC FIFO and accelerator with the basic configuration. More...
|
| |
| uint32_t | enet_mac_configure_controller (enet_dev_if_t *enetIfPtr) |
| | the ENET controller with the basic configuration. More...
|
| |
| uint32_t | enet_mac_deinit (enet_dev_if_t *enetIfPtr) |
| | Deinit the ENET device. More...
|
| |
| uint32_t | enet_mac_update_rxbd (enet_dev_if_t *enetIfPtr, bool isBufferUpdate) |
| | Updates the receive buffer descriptor. More...
|
| |
| bool | enet_mac_rx_error_stats (enet_dev_if_t *enetIfPtr, uint32_t data) |
| | Processes the ENET receive frame error statistics. More...
|
| |
| void | enet_mac_tx_error_stats (enet_dev_if_t *enetIfPtr, void *curBd) |
| | Processes the ENET transmit frame statistics. More...
|
| |
| uint32_t | enet_mac_tx_cleanup (enet_dev_if_t *enetIfPtr) |
| | ENET transmit buffer descriptor cleanup. More...
|
| |
| uint32_t | enet_mac_receive (enet_dev_if_t *enetIfPtr, enet_mac_packet_buffer_t *packBuffer) |
| | Receives ENET packets. More...
|
| |
| uint32_t | enet_mac_send (enet_dev_if_t *enetIfPtr, uint8_t *packet, uint32_t size) |
| | Transmits ENET packets. More...
|
| |
| void | enet_mac_rx_isr (void *enetIfPtr) |
| | The ENET receive interrupt handler. More...
|
| |
| void | enet_mac_tx_isr (void *enetIfPtr) |
| | The ENET transmit interrupt handler. More...
|
| |
| void | enet_mac_calculate_crc32 (enetMacAddr address, uint32_t *crcValue) |
| | Calculates the CRC hash value. More...
|
| |
| uint32_t | enet_mac_add_multicast_group (uint32_t instance, enet_multicast_group_t *multiGroupPtr, enetMacAddr address) |
| | Adds the ENET device to a multicast group. More...
|
| |
| uint32_t | enet_mac_leave_multicast_group (uint32_t instance, enet_multicast_group_t *multiGroupPtr, enetMacAddr address) |
| | Moves the ENET device from a multicast group. More...
|
| |
| uint32_t | enet_mac_init (enet_dev_if_t *enetIfPtr, enet_rxbd_config_t *rxbdCfg, enet_txbd_config_t *txbdCfg) |
| | Initializes the ENET with the basic configuration. More...
|
| |
| void | enet_mac_enqueue_buffer (void **queue, void *buffer) |
| | Enqueues a data buffer to the buffer queue. More...
|
| |
| void * | enet_mac_dequeue_buffer (void **queue) |
| | Dequeues a buffer from the buffer queue. More...
|
| |
Overview
The ENET driver receives data from and transmits data to the wired network. The enhanced 1588 feature supports clock synchronization.
ENET device data structure
The ENET device data structure,
enet_dev_if_t, includes configuration structure, application structure, and data context structure. This structure should be initialized before the ENET device initialization function. Then, the data structure is passed from the API layer to the device.
Configuration structure
The ENET device data structure uses the
enet_mac_config_t and the
enet_phy_config_t configuration structure for MAC and PHY configurations. This allows users to configure the most common settings of the ENET peripheral. The
enet_mac_config_t mac configuration structure includes the receive and transmit buffer descriptor numbers, data buffer number, buffer size, MII/RMII mode, MAC loop mode. The
enet_phy_config_t PHY configuration structure includes the PHY address and PHY loop mode, which need to be configured. If the PHY address is unknown, use the isPhyAutoDiscover flag in MAC
enet_mac_config_t configuration to find the PHY address. Note:
- The recommended maximum frame length is 1518 or 1522(VLAN).
- The receive buffer size should use the maximum frame size 1518 or 1522(VLAN). In this case, the rxLargeBuffer is not needed and the rxLargeBufferNumber should be set to 0.
- If a small buffer size is used and the stack you choose does not support a frame with fragments, the drivers will allocate a large external buffer and do memcopy for collecting frames. In this case, the rxLargeBufferNumber value needs to be at least 4.
- In current driver, transmit frames are with crc.
Application structure
The ENET device data structure uses the
enet_mac_api_t and the enet_phy_api_t as the driver API structure. This API structure allows higher layers to call specific device functions. This is still flexible for different stack porting. The MAC and PHY application structure are defined like this:
{
enet_mac_close,
#if !ENET_RECEIVE_ALL_INTERRUPT
#endif
};
const enet_phy_api_t g_enetPhyApi =
{
phy_auto_discover,
phy_init,
phy_get_link_speed,
phy_get_link_status,
phy_get_link_duplex,
};
Context data structure
The ENET device data structure uses the
enet_mac_context_t to keep the user configuration and keep track of data transfer. Data receive and transmit is easily managed with this context structure.
Initialization
To initialize the ENET module, do this:
- First, initialize the ENET MAC and PHY configuration structures, and initialize the upper layer callback function.
- Call the enet_mac_init() function through the enet_mac_api_t API structure in the enet_dev_if_t and pass in the enet_dev_if_t device data structure. This function enables the ENET module.
This is an example code to initialize the ENET device data structure:
{
ENET_RX_LARGE_BUFFER_NUM,
ENET_TX_RING_LEN,
{0},
false,
false,
false,
{true, true, false, false, false},
{true, true, false},
false,
true,
ENET_MII_CLOCK,
#if FSL_FEATURE_ENET_SUPPORT_PTP
ENET_PTP_RING_BUFFER_NUM,
false,
#endif
};
{{0, false }};
enetIfPtr->
macCfgPtr = &g_enetMacCfg[device];
enetIfPtr->
phyCfgPtr = &g_enetPhyCfg[device];
enetIfPtr->
phyApiPtr = (
void *)&g_enetPhyApi;
#if ENET_RECEIVE_ALL_INTERRUPT
enetIfPtr->enetNetifcall = enet_Callback;
#endif
enet_mac_buffer_init(enetIfPtr, &rxbdCfg, &txbdCfg);
((enet_phy_api_t *)(enetIfPtr->
phyApiPtr))->phy_init(enetIfPtr);
Data Receive
There are two approaches on ENET receive and the MACRO ENET_RECEIVE_ALL_INTERRUPT is used to choose the approach.
- interrupt add poll(define ENET_RECEIVE_ALL_INTERRUPT with 0)
- interrupt only (define ENET_RECEIVE_ALL_INTERRUPT with 1)
Interrupt add task poll approach: The ENET driver receives data directly from the buffer descriptor to the upper layer. To shorten the receive process time on the receive interrupt, receive data uses the interrupt and poll combination:
- Receive interrupt: releases the receive synchronize signal(enetReceiveSync).
- Poll: receives task and waits for the receive synchronize signal when no data is received. The receive data returns the address and data length of the received data. To receive data from the ENET device, create a receive task as follows:
.......................................
{
uint8_t *packet;
uint16_t length;
while(1)
{
result = enetIfPtr->
macApiPtr->enet_mac_receive(enetIfPtr, &packetBuffer[0]);
{
}
....................
....................
}
}
{
if (!enetIfPtr)
{
return;
}
{
}
}
Interrupt only approach for MAC receive:
The ENET driver receives data directly from the buffer descriptor to the upper layer.
In this case, data is received on receive interrupt handler:
1. Receive interrupt handler calls the receive peripheral driver.
2. Receive peripheral driver calls the initialized callback function.
3. The callback function checks the protocol and delivers the received data to the upper layer of the TCP/IP stack.
These are the details:
~~~~~{.c}
{
if(!enetIfPtr)
{
return;
}
{
}
}
.......................................
{
void *curBd;
uint32_t length;
uint8_t *packet;
uint32_t controlStatus;
{
}
if(!curBd)
{
}
...........
enetIfPtr->enetNetifcall(enetIfPtr, packet, length);
..........
return kStatus_ENET_Success;
}
uint32_t void enet_callback(void *param, uint8_t *packet, uint32_t length)
{
uint16_t type;
type = NTOHS(*(uint16_t *)&((enet_etherent_header_t *)packet)->type);
if(pcbPtr)
{
pcbPtr->FRAG[0].LENGTH = length;
pcbPtr->FRAG[0].FRAGMENT = packet;
pcbPtr->PRIVATE = (void *)enetIfPtr;
switch(type)
{
break;
case ENETPROT_ARP:
break;
case ENETPROT_IP6:
break;
case ENETPROT_ETHERNET:
enet_ptp_service_l2packet(enetIfPtr, packet, length);
break;
default:
break;
}
}
else
{
enetIfPtr->stats.statsRxMissed++;
}
}
Data Transmit
Data Transmit transmits data from the TCP/IP layer to the device and, then, to the network. The data transmit function should be used like this: PCB_PTR is the data buffer structure of the frame which contains many
PCB_FRAGMENT(including the data buffer and length).
{
uint16_t length = 0;
if( frame == NULL)
{
return ENETERR_ALLOC;
}
for(fragPtr = packet->FRAG; fragPtr->
LENGTH; fragPtr++)
{
}
}
#Notification:
- TWR-MK70F120M board only routes the RMII interface signals from the CPU board to the primary connectors. Hence, the rmiiCfgMode in the enet_mac_config_t should be set to the kEnetCfgRmii. TWR-MK64F120M board can configure both RMII and MII modes.
- Jumper setting When ENET is uses the RMII interface signals by default, the RMII input clock must be kept in phase with the clock supplied to the external PHY. Jumpers should be set like this:
- TWR-SER J2 shunt across 3-4 , J3 shunt across 2-3, J12 shunt across 9-10
- TWR-MK64f120M board make sure J32 jumper is on to disable the OSC on the CPU board.
- TWR-MK70f120M board make sure J18 jumper is on to disable the OSC on the CPU board. When ENET chooses the MII interface signals, the jumper should be set as: TWR-SER J2 shunt across 1-2, J12 no shunt across 9-10.